/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.phoenix.repository;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jcr.NodeIterator;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;

/**
 * Jigsaw server
 * 
 * @author <a href="shamphone@gmail.com">Li XiongFeng</a>
 * @date 2012-1-2
 * @version 1.0.0
 */
public abstract class MappedNode extends GeneralNode implements Map<String, Object> {

	@Override
	public int size() {
		try {
			return (int) (this.getProperties().getSize());
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}
	}

	@Override
	public boolean isEmpty() {
		return false;
	}

	@Override
	public boolean containsKey(Object key) {
		try {
			return this.getProperties(key.toString()) != null;
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}
	}

	@Override
	public boolean containsValue(Object value) {
		return false;
	}

	@Override
	public Object get(Object key) {
		String name = key.toString();

		//Object nodes;
		try {
			if (name.equalsIgnoreCase("parent"))
				return this.getParent();
			else if (name.equalsIgnoreCase("path"))
				return this.getPath();
			else if (name.equalsIgnoreCase("identifier"))
				return this.getIdentifier();
			else if (name.equalsIgnoreCase("id"))
				return this.getIdentifier();
			else if (name.equals("index"))
				return this.getIndex();
			else if (name.equals("name"))
				return this.getName();
			else if (name.equals("type"))
				return this.getPrimaryNodeType();
			else if (name.equals("properties"))
				return this.getProperties();
			else if (name.equals("definition"))
				return this.getDefinition();
			else if (name.equals("depth"))
				return this.getDepth();
			else if (name.equals("name"))
				return this.getNodes();
			else if (name.equals("references"))
				return this.getReferences();
			if(this.hasNode(name)){
				NodeIterator nodes = this.getNodes(name);
				if(nodes.getSize()==1)
					return nodes.nextNode();
				return nodes;
			}
			else if(this.hasProperty(name)){
				return this.getProperty(name);
			}
			return null;
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}

	}

	@Override
	public Object put(String key, Object value) {
		String name = key.toString();
		Object old;
		try {
			old = this.getProperty(name);
			this.setProperty(name, value.toString());
			return old;
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}

	}

	@Override
	public Object remove(Object key) {
		String name = key.toString();
		try {
			Object old = this.getProperty(name);
			this.setProperty(name, (String) null);
			return old;
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}
	}

	@Override
	public void putAll(Map<? extends String, ? extends Object> m) {
		for (String key : m.keySet())
			this.put(key, m.get(key));
	}

	@Override
	public void clear() {
	}

	@Override
	public Set<String> keySet() {
		Set<String> keys = new HashSet<String>();
		try {
			for (PropertyIterator properties = this.getProperties(); properties.hasNext();) {
				keys.add(properties.nextProperty().getName());
			}
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}
		return keys;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Collection values() {
		List<String> values = new ArrayList<String>();
		try {
			for (PropertyIterator properties = this.getProperties(); properties.hasNext();) {
				values.add(properties.nextProperty().getString());
			}
		} catch (RepositoryException e) {
			throw new RepositoryRuntimeException(e);
		}
		return values;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Set entrySet() {
		return null;
	}

}
